package concurrency.chapter7;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * @author honway.liu
 * @date 2019-06-06 23:21
 * @email gm100861@gmail.com
 * @blog http://linuxsogood.org
 * Lock实现类
 */
public class BooleanLock implements Lock {

    private Thread currentThread;

    private volatile boolean lockStatus;

    private List<Thread> blockedThreadList;

    public BooleanLock() {
        this.lockStatus = false;
        blockedThreadList = new LinkedList<>();
    }

    @Override
    public synchronized void lock() {
        // 锁已经被别的线程获取到, 当前线程需要等待
        while (lockStatus) {
            try {
                System.out.println(Thread.currentThread().getName() + "获取锁失败,进入等待队列,当前持有者线程名称:" + currentThread.getName());
                blockedThreadList.add(Thread.currentThread());
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 当前锁可以没有被别的线程获取
        lockStatus = true;
        System.out.println(Thread.currentThread().getName() + "获取锁成功");
        currentThread = Thread.currentThread();
        blockedThreadList.remove(Thread.currentThread());
    }

    @Override
    public synchronized void lock(long timeout) throws TimeOutException{

    }

    /**
     * 只有拥有锁的进程,才能解锁.其它进程不能进行解锁.
     */
    @Override
    public synchronized void unlock() {
        System.out.println(Thread.currentThread().getName() + "开始解锁");
        if (Thread.currentThread() == currentThread) {
            currentThread = null;
            lockStatus = false;
            notifyAll();
        }
    }

    /**
     * 返回阻塞的线程队列
     * 出于安全考虑,要返回一个不可变的集合列表,以防止修改
     * @return
     */
    public List<Thread> getBlockedThreadList() {
        return Collections.unmodifiableList(blockedThreadList);
    }
}
